<template>
  <div class="search">
    <span class="role">房间类型：</span>
    <el-select v-model="roomTypeId" class="select-role" size="small">
      <el-option
        v-for="item in roomTypesData"
        :key="item.roomTypeId"
        :label="item.roomTypeName"
        :value="item.roomTypeId"
      />
    </el-select>
    <span class="role">房间状态：</span>
    <el-select v-model="roomStateId" class="select-role" size="small">
      <el-option
        v-for="item in roomStatesData"
        :key="item.roomStateId"
        :label="item.roomStateName"
        :value="item.roomStateId"
      />
    </el-select>
    <el-button 
      size="small" 
      type="success" 
      @click="loadTable"
    >查询</el-button>
    <el-button 
      size="small" 
      type="info" 
      @click="toExcel"
    >导出Excel</el-button>
    <el-button 
      size="small" 
      type="primary" 
      @click="openDrawerHandler"
    >添加</el-button>
  </div>
  <el-table size="small" :data="tableData" style="width: 99%">
    <el-table-column prop="roomId" label="房间号" width="100" />
    <el-table-column prop="roomType.roomTypeName" label="房间类型" />
    <el-table-column prop="roomType.roomTypePrice" label="房间价格" />
    <el-table-column prop="roomType.bedNum" label="床位数" />
    <el-table-column prop="roomState.roomStateName" label="房间状态">
      <template #default="scope">
        <el-tag
          size="small"
          v-if="scope.row.roomState.roomStateId === '1'"
          type="success"
        >
          {{ scope.row.roomState.roomStateName }}
        </el-tag>
        <el-tag
          size="small"
          v-else-if="scope.row.roomState.roomStateId === '2'"
          type="danger"
        >
          {{ scope.row.roomState.roomStateName }}
        </el-tag>
        <el-tag
          size="small"
          v-else
          type="info"
        >
          {{ scope.row.roomState.roomStateName }}
        </el-tag>
      </template>
    </el-table-column>
    <el-table-column label="操作" width="250">
      <template #default="scope">
        <el-button 
          size="small" 
          type="primary" 
          @click="openDialog(scope.row)"
        >照片</el-button>
        <el-button
          size="small"
          type="danger"
          @click="handleDelete(scope.row)"
        >删除</el-button>
        <el-button 
          size="small" 
          type="warning" 
          v-if="scope.row.roomState.roomStateId !== '3'"
          @click="handleEdit(scope.row)"
        >编辑</el-button>
      </template>
    </el-table-column>
  </el-table>
  <div class="pages">
    <el-pagination background small layout="prev, pager, next" :total="total" :page-size="pageSize" v-model:current-page="pageNo" @current-change="curChange" />
  </div>
  <el-drawer
    v-model="openDrawer"
    :title="`${isAdd ? '添加' : '编辑'}房间`"
    :before-close="handleClose"
    size="40%"
  >
    <div class="item">
      <span>房间编号：</span>
      <div>
        <el-input v-model="formData.roomId" placeholder="请输入房间编号" size="small" />
      </div>
    </div>
    <div class="item">
      <span>房间类型：</span>
      <div>
        <el-select v-model="formData.roomTypeId" class="select-role" size="small">
          <el-option
            v-for="item in roomTypesData"
            :key="item.roomTypeId"
            :label="item.roomTypeName"
            :value="item.roomTypeId"
          />
        </el-select>
      </div>
    </div>
    <div class="item">
      <span>房间状态：</span>
      <div>
        <el-select v-model="formData.roomStateId" class="select-role" size="small">
          <el-option
            v-for="item in roomStates"
            :key="item.roomStateId"
            :label="item.roomStateName"
            :value="item.roomStateId"
          />
        </el-select>
      </div>
    </div>
    <div class="item">
      <span>房间描述：</span>
      <div>
        <QuillEditor contentType="html" theme="snow" style="height: 300px;" v-model:content="formData.description" v-if="openDrawer" />
      </div>
    </div>
    <div class="item">
      <span></span>
      <div>
        <el-button 
          size="small" 
          type="primary" 
          @click="editRoom"
        >{{isAdd ? '添加' : '编辑'}}</el-button>
        <el-button 
          size="small" 
          @click="clearInput"
        >重置</el-button>
      </div>
    </div>
  </el-drawer>
  <el-dialog
    v-model="dialogVisible"
    title="房间照片"
    width="60%"
    :before-close="handleCloseDialog"
  >
    <el-upload
      v-model:file-list="fileList"
      :action="ROOM_UPLOAD_URL"
      list-type="picture-card"
      :limit="9"
      :on-preview="handlePictureCardPreview"
      :on-remove="handleRemove"
      :on-success="handlePicSuccess"
      :before-upload="beforePicUpload"
    >
      <el-icon><Plus /></el-icon>
    </el-upload>

    <el-dialog v-model="dialogPreview" width="50%">
      <img w-full :src="dialogImageUrl" alt="Preview Image" />
    </el-dialog>
  </el-dialog>
</template>

<script>
import {reactive, toRefs, computed} from 'vue';
import { Plus } from '@element-plus/icons-vue'
import {list, add, update, del} from '../../api/room';
import {list as getRoomStateList, listToAdd} from '../../api/roomState';
import {getRoomTypeList} from '../../api/roomType';
import {add as addRoomImg, list as getRoomImgs, del as deleteRoomImg} from '../../api/roomImg';
import {$confirm} from '../../utils/msg';
import {xlsx} from '../../utils/xlsx';
import {ROOM_UPLOAD_URL, ROOM_PHOTO_URL} from '../../config/constant';

export default {
  name: 'Room',
  components: {Plus},
  setup(){
    const state = reactive({
      tableData: [], //房间列表数据
      total: 0, //总条目数
      pageNo: 1, //当前页
      pageSize: 5, //每页显示条数
      openDrawer: false, //是否显示 Drawer
      formData: {
        roomTypeId: '0', //房间类型编号
        roomStateId: '0', //房间状态编号
        roomId: '', //房间编号
        description: '', //房间描述
        id: '', //编辑时的原房间编号
      },
      isAdd: true, //是否添加房间
      roomTypeId: '0', //房间类型 id -搜索
      roomTypesData: [], //房间类型数据
      roomStateId: '0', //房间状态 id -搜索
      roomStatesData: [], //房间状态数据-搜索
      roomStatesDataAdd: [], //房间状态数据-添加
      dialogVisible: false, //是否显示对话框
      dialogPreview: false, //是否显示照片预览对话框
      ROOM_UPLOAD_URL, //上传房间照片地址
      ROOM_PHOTO_URL, //查看房间照片地址
      fileList: [], //房间照片
      dialogImageUrl: '', //预览图片地址
    });

    const roomStates = computed(() => {
      let roomStatesArr = [];

      if(state.isAdd){
        //添加房间
        roomStatesArr = state.roomStatesDataAdd;
      }else{
        //编辑房间
        roomStatesArr = state.roomStatesData;
      }

      return roomStatesArr;
    });

    //加载房间列表数据
    const loadTable = async () => {
      const params = {
        pageIndex: state.pageNo,
        pageSize: state.pageSize,
        roomTypeId: state.roomTypeId,
        roomStateId: state.roomStateId,
      }

      const {data: roomData, count, pageIndex, pageSize} = await list(params);

      state.tableData = roomData;
      state.total = count;
      state.pageSize = pageSize;
      state.pageNo = pageIndex;
    }

    loadTable();

    //加载房间类型数据
    const loadRoomTypes = async () => {
      const data = await getRoomTypeList();

      data.unshift({
        roomTypeId: '0',
        roomTypeName: '请选择房间类型',
      });

      state.roomTypesData = data;
    }

    loadRoomTypes();

    //加载房间状态数据-查询
    const loadRoomStates = async () => {
      const data = await getRoomStateList();

      data.unshift({
        roomStateId: '0',
        roomStateName: '请选择房间状态',
      });

      state.roomStatesData = data;
    }

    loadRoomStates();

    //加载房间状态数据-添加
    const loadRoomStatesAdd = async () => {
      const data = await listToAdd();

      data.unshift({
        roomStateId: '0',
        roomStateName: '请选择房间状态',
      });

      state.roomStatesDataAdd = data;
    }

    loadRoomStatesAdd();

    //current-page 改变时触发
    const curChange = (current) => {
      state.pageNo = current;
      loadTable();
    }

    //添加、编辑房间
    const editRoom = async () => {
      let result = false;

      if(state.isAdd){
        //添加
        delete state.formData.id;
        result = await add(state.formData);
      }else{
        //编辑
        result = await update(state.formData);
      }

      if(result){
        //成功
        loadTable();
      }
    }

    //打开抽屉
    const openDrawerHandler = () => {
      state.isAdd = true;
      state.openDrawer = true;
    }

    //点击重置按钮
    const clearInput = () => {
      state.formData = {
        roomTypeId: '0', //房间类型编号
        roomStateId: '0', //房间状态编号
        roomId: '', //房间编号
        description: '', //房间描述
      }

      document.querySelector('.ql-editor').innerHTML = '';
    }

    //关闭抽屉
    const handleClose = () => {
      clearInput();
      state.openDrawer = false;
    }

    //点击编辑按钮
    const handleEdit = (row) => {
      const obj = {}

      for(const key in row){
        if(typeof row[key] === 'object'){
          //值是对象
          for(const secondaryKey in row[key]){
            if(secondaryKey === 'roomTypeId' || secondaryKey === 'roomStateId'){
              //房间类型编号或者房间状态编号
              obj[secondaryKey] = row[key][secondaryKey];
            }
          }
        }else{
          //值不是对象
          obj[key] = row[key];

          if(key === 'roomId'){
            //原房间编号
            obj.id = row[key];
          }
        }
      }

      state.formData = obj;
      state.isAdd = false;
      state.openDrawer = true;
    }

    //点击删除按钮
    const handleDelete = async (row) => {
      await $confirm('确定删除该房间吗？');

      const {roomId} = row;
      const result = await del({roomId});

      if(result){
        //成功
        loadTable();
      }
    }

    let currentRoomId = '';

    //点击照片按钮
    const openDialog = async (row) => {
      const {roomId} = row;

      currentRoomId = roomId;

      const list = await getRoomImgs({roomId});

      state.fileList = list.map(img => {
        const {imgUrl, roomImgId} = img;

        return {
          name: imgUrl,
          url: ROOM_PHOTO_URL + imgUrl,
          roomImgId,
        }
      });
      
      state.dialogVisible = true;
    }

    //文件上传成功时的钩子
    const handlePicSuccess = async (
      response,
      uploadFile
    ) => {
      const {success, filename} = response;

      if(success){
        //文件上传成功
        const params = {
          roomId: currentRoomId,
          imgUrl: filename,
        }

        await addRoomImg(params);
      }
    }

    //上传文件之前的钩子
    const beforePicUpload = (rawFile) => {
      if (rawFile.type !== 'image/jpeg' && rawFile.type !== 'image/png') {
        ElMessage.error('照片的格式必须为JPG或PNG!')
        return false
      } else if (rawFile.size / 1024 / 1024 > 2) {
        ElMessage.error('照片文件大小不能超过2MB!')
        return false
      }
      return true
    }

    //文件列表移除文件时的钩子
    const handleRemove = async (uploadFile, uploadFiles) => {
      const {roomImgId, name} = uploadFile;

      const params = {
        roomImgId,
        filename: name,
      }

      await deleteRoomImg(params);
    }

    //照片对话框：关闭前的回调
    const handleCloseDialog = (done) => {
      state.fileList = [];
      done();
    }

    //点击文件列表中已上传的文件时的钩子
    const handlePictureCardPreview = (uploadFile) => {
      state.dialogImageUrl = uploadFile.url;
      state.dialogPreview = true;
    }

    //导出 excel
    const toExcel = () => {
      const excelData = state.tableData.map(room => {
        const {roomId, roomType, roomState} = room;

        return {
          roomId,
          roomTypeName: roomType.roomTypeName,
          roomTypePrice: roomType.roomTypePrice,
          bedNum: roomType.bedNum,
          roomStateName: roomState.roomStateName,
        }
      });

      const excelHeader = {
        roomId: '房间号',
        roomTypeName: '房间类型',
        roomTypePrice: '房间价格',
        bedNum: '床位数',
        roomStateName: '房间状态',
      }

      xlsx(excelData, excelHeader, '房间信息');
    }

    return {
      ...toRefs(state),
      curChange,
      editRoom,
      openDrawerHandler,
      handleClose,
      handleEdit,
      handleDelete,
      clearInput,
      loadTable,
      roomStates,
      handlePicSuccess,
      beforePicUpload,
      openDialog,
      handleRemove,
      handleCloseDialog,
      handlePictureCardPreview,
      toExcel,
    }
  },
}
</script>

<style lang="scss" scoped>
.pages {
  padding-top: 10px;
}
.item {
  display: flex;
  align-items: center;
  margin-bottom: 10px;
  span {
    width: 70px;
    font-size: 14px;
    text-align: right;
  }
  div {
    flex: 1;
  }
}
</style>